package tech.xiaozai.rbac.security;

import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTCreationException;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.auth0.jwt.interfaces.JWTVerifier;

import java.util.Date;
import java.util.List;

/**
 * @author xiaozai
 * @version 1.0
 * @date 2020-09-22 19:21
 *
 *  令牌管理者
 */

public class JWTWorker {


    /**默认的令牌有效期
     *
     */
    private Long ms=10*24*60*60000L;

    /**密钥
     *
     */
    private String secret = "iloveyou";

    /**
     *  制作token
     * @param userId
     * @param roleIds
     * @return
     */
    public String createToken(Long userId, List<String> roleIds){
        try {
            Algorithm algorithm = Algorithm.HMAC256(secret);
            String token = JWT.create()
                    .withIssuer("auth0")
                    .withExpiresAt(new Date(System.currentTimeMillis()+ms))
                    .withClaim("userId",userId)
                    .withClaim("roleIds",roleIds)
                    .sign(algorithm);

            return token;

        } catch (JWTCreationException exception){
            exception.printStackTrace();
            throw exception;
            //Invalid Signing configuration / Couldn't convert Claims.
        }
    }


    /**
     *   验证token,有效时返回，无效时抛异常
     * @param token
     * @return
     */
    public DecodedJWT verify(String token){
        try {
            Algorithm algorithm = Algorithm.HMAC256(secret);
            JWTVerifier verifier = JWT.require(algorithm)
                    .withIssuer("auth0")
                    .build(); //Reusable verifier instance
            DecodedJWT jwt = verifier.verify(token);
            return jwt;
        } catch (JWTVerificationException exception){
            //Invalid signature/claims
            exception.printStackTrace();
            throw exception;
        }
    }

    /**
     *  刷新token, 快过期的令牌得刷一下,
     */

    public String refresh(String token){
        try {
            DecodedJWT jwt = JWT.decode(token);
            return createToken(jwt.getClaim("userId").asLong(),jwt.getClaim("roleIds").asList(String.class));
        } catch (JWTDecodeException exception){
            //Invalid token
            exception.printStackTrace();
            throw exception;
        }
    }
}
